Add private function to get the aux info structure fo the widget.
authorOwen Taylor <otaylor@redhat.com>
Thu, 29 Mar 2001 23:02:30 +0000 (23:02 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 29 Mar 2001 23:02:30 +0000 (23:02 +0000)
Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
to get the aux info structure fo the widget.

* gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
above function.

        [ Patch from  Havoc Pennington  <hp@redhat.com> ]

* gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
to get the size of the window manager frame, basically the same
code that gdk_window_get_root_origin() had
(gdk_window_get_root_origin): use gdk_window_get_frame_extents()

* gtk/gtkwindow.c (gtk_window_set_default_size): use
gdk_window_resize() if the window is realized and resizeable

* gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
typo so that setting gravity works

* gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
allocation if auto_shrink is on, even if the default size
has not changed.

* gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
g_return_if_fail

18 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/gtk/tmpl/gtkwidget.sgml
gdk/gdkwindow.h
gdk/x11/gdkwindow-x11.c
gtk/gtklabel.c
gtk/gtkscrolledwindow.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c
gtk/gtkwindow.h
gtk/testgtk.c
tests/testgtk.c

index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 87d1265849ef10cef02ebf11055ef93d8e570404..2b174c1989ac909e57ffaf7b024ade7f41418958 100644 (file)
@@ -1,3 +1,31 @@
+Wed Mar 28 20:30:26 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.[ch] (_gtk_widget_get_aux_info): Add private function
+       to get the aux info structure fo the widget.
+
+       * gtk/gtklabel.c gtk/gtkscrolledwindow.c gtk/gtkwindow.c: Use
+       above function.
+
+        [ Patch from  Havoc Pennington  <hp@redhat.com> ]
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_get_frame_extents): function
+       to get the size of the window manager frame, basically the same
+       code that gdk_window_get_root_origin() had
+       (gdk_window_get_root_origin): use gdk_window_get_frame_extents()
+
+       * gtk/gtkwindow.c (gtk_window_set_default_size): use
+       gdk_window_resize() if the window is realized and resizeable
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_set_geometry_hints): fix
+       typo so that setting gravity works
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): don't ever use
+       allocation if auto_shrink is on, even if the default size
+       has not changed.
+
+       * gtk/gtkwidget.c (gtk_widget_render_icon): remove bogus
+       g_return_if_fail
+
 Thu Mar 29 16:29:12 2001  Jonathan Blandford  <jrb@webwynk.net>
 
        * gtk/gtkliststore.c (gtk_list_store_iter_changed): Massive
index 253f211395f8d1aaa776a0fd53e79e8d21342266..6b2b10024bb66d9e4b70b5a80bb43d004b36f2df 100644 (file)
@@ -294,6 +294,8 @@ GtkWidget
 @y: 
 @width: 
 @height: 
+@x_set: 
+@y_set: 
 
 <!-- ##### STRUCT GtkWidgetShapeInfo ##### -->
 <para>
index dbb91da22faca0ec1fe0a0c67377cab3d92cce23..2c8d6bab1ce96d1a02aad05424a3ecef83da6b34 100644 (file)
@@ -416,6 +416,8 @@ gboolean      gdk_window_get_deskrelative_origin (GdkWindow   *window,
 void         gdk_window_get_root_origin (GdkWindow       *window,
                                          gint            *x,
                                          gint            *y);
+void          gdk_window_get_frame_extents (GdkWindow     *window,
+                                            GdkRectangle  *rect);
 GdkWindow*    gdk_window_get_pointer    (GdkWindow       *window,
                                          gint            *x,
                                          gint            *y,
index b53146f424379a1c7a7d7ffbd1741bbc70575460..1a7c80a346ef12c0a4b2f4166492124ea9ee586a 100644 (file)
@@ -1676,6 +1676,19 @@ gdk_window_get_geometry (GdkWindow *window,
     }
 }
 
+/**
+ * gdk_window_get_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ * 
+ * Obtains the position of a window in root window coordinates.
+ * (Compare with gdk_window_get_position() and
+ * gdk_window_get_geometry() which return the position of a window
+ * relative to its parent window.)
+ * 
+ * Return value: not meaningful, ignore
+ **/
 gint
 gdk_window_get_origin (GdkWindow *window,
                       gint      *x,
@@ -1708,6 +1721,21 @@ gdk_window_get_origin (GdkWindow *window,
   return return_val;
 }
 
+/**
+ * gdk_window_get_deskrelative_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ * 
+ * This gets the origin of a #GdkWindow relative to
+ * an Enlightenment-window-manager desktop. As long as you don't
+ * assume that the user's desktop/workspace covers the entire
+ * root window (i.e. you don't assume that the desktop begins
+ * at root window coordinate 0,0) this function is not necessary.
+ * It's deprecated for that reason.
+ * 
+ * Return value: not meaningful
+ **/
 gboolean
 gdk_window_get_deskrelative_origin (GdkWindow *window,
                                    gint      *x,
@@ -1772,10 +1800,48 @@ gdk_window_get_deskrelative_origin (GdkWindow *window,
   return return_val;
 }
 
+/**
+ * gdk_window_get_root_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X position of window frame
+ * @y: return location for Y position of window frame
+ *
+ * Obtains the top-left corner of the window manager frame in root
+ * window coordinates.
+ * 
+ **/
 void
 gdk_window_get_root_origin (GdkWindow *window,
                            gint      *x,
                            gint      *y)
+{
+  GdkRectangle rect;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  gdk_window_get_frame_extents (window, &rect);
+
+  if (x)
+    *x = rect.x;
+
+  if (y)
+    *y = rect.y;
+}
+
+/**
+ * gdk_window_get_frame_extents:
+ * @window: a #GdkWindow
+ * @rect: rectangle to fill with bounding box of the window frame
+ *
+ * Obtains the bounding box of the window, including window manager
+ * titlebar/borders if any. The frame position is given in root window
+ * coordinates. To get the position of the window itself (rather than
+ * the frame) in root window coordinates, use gdk_window_get_origin().
+ * 
+ **/
+void
+gdk_window_get_frame_extents (GdkWindow    *window,
+                              GdkRectangle *rect)
 {
   GdkWindowObject *private;
   Window xwindow;
@@ -1784,15 +1850,16 @@ gdk_window_get_root_origin (GdkWindow *window,
   Window *children;
   unsigned int nchildren;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (rect != NULL);
   
   private = (GdkWindowObject*) window;
-  if (x)
-    *x = 0;
-  if (y)
-    *y = 0;
-
+  
+  rect->x = 0;
+  rect->y = 0;
+  rect->width = 1;
+  rect->height = 1;
+  
   if (GDK_WINDOW_DESTROYED (window))
     return;
   
@@ -1822,10 +1889,10 @@ gdk_window_get_root_origin (GdkWindow *window,
       
       if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
        {
-         if (x)
-           *x = wx;
-         if (y)
-           *y = wy;
+          rect->x = wx;
+          rect->y = wy;
+          rect->width = ww;
+          rect->height = wh;
        }
     }
 }
@@ -3442,7 +3509,6 @@ update_pos (gint new_root_x,
           w += dx;
           h += dy;
           break;
-
         }
 
       w = MAX (w, 1);
index 4de995ef2663f42b4f54b5944546decf76802ca4..17448490a535ceefac1cf0bd2c37096b3215f47a 100644 (file)
@@ -1013,7 +1013,7 @@ gtk_label_ensure_layout (GtkLabel *label,
       gint width, height;
       gint real_width;
 
-      aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
+      aux_info = _gtk_widget_get_aux_info (widget, FALSE);
       if (aux_info && aux_info->width > 0)
        {
          pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE);
index 28a7c5eb19586202297a8d0c4b78f97d581c5b4b..d220614c87033a8879c610814d38d534c46e41a8 100644 (file)
@@ -666,20 +666,14 @@ gtk_scrolled_window_size_request (GtkWidget      *widget,
   
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     {
-      static guint quark_aux_info = 0;
-
-      if (!quark_aux_info)
-       quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
-
       gtk_widget_size_request (bin->child, &child_requisition);
 
       if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
        requisition->width += child_requisition.width;
       else
        {
-         GtkWidgetAuxInfo *aux_info;
+         GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
 
-         aux_info = gtk_object_get_data_by_id (GTK_OBJECT (bin->child), quark_aux_info);
          if (aux_info && aux_info->width > 0)
            {
              requisition->width += aux_info->width;
@@ -693,9 +687,7 @@ gtk_scrolled_window_size_request (GtkWidget      *widget,
        requisition->height += child_requisition.height;
       else
        {
-         GtkWidgetAuxInfo *aux_info;
-
-         aux_info = gtk_object_get_data_by_id (GTK_OBJECT (bin->child), quark_aux_info);
+         GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
          if (aux_info && aux_info->height > 0)
            {
              requisition->height += aux_info->height;
index 7274923db44aae041fbf6bc9d5f7ff6d18f4d757..175461e7d83bde5a25012a5c514613546c064faf 100644 (file)
@@ -198,6 +198,8 @@ static gboolean gtk_widget_real_activate_mnemonic  (GtkWidget *widget,
 static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
 static void             gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
 
+static void  gtk_widget_do_uposition (GtkWidget *widget);
+     
 static gpointer         parent_class = NULL;
 static guint            widget_signals[LAST_SIGNAL] = { 0 };
 
@@ -837,6 +839,7 @@ gtk_widget_set_arg (GtkObject   *object,
                    guint        arg_id)
 {
   GtkWidget *widget;
+  GtkWidgetAuxInfo *aux_info;
 
   widget = GTK_WIDGET (object);
 
@@ -851,10 +854,26 @@ gtk_widget_set_arg (GtkObject   *object,
       gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT (*arg)), widget);
       break;
     case ARG_X:
-      gtk_widget_set_uposition (widget, GTK_VALUE_INT (*arg), -2);
+      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+      if (GTK_VALUE_INT (*arg) == -1)
+       aux_info->x_set = FALSE;
+      else
+       {
+         aux_info->x_set = TRUE;
+         aux_info->x = GTK_VALUE_INT (*arg);
+       }
+      gtk_widget_do_uposition (widget);
       break;
     case ARG_Y:
-      gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT (*arg));
+      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+      if (GTK_VALUE_INT (*arg) == -1)
+       aux_info->y_set = FALSE;
+      else
+       {
+         aux_info->y_set = TRUE;
+         aux_info->y = GTK_VALUE_INT (*arg);
+       }
+      gtk_widget_do_uposition (widget);
       break;
     case ARG_WIDTH:
       gtk_widget_set_usize (widget, GTK_VALUE_INT (*arg), -2);
@@ -960,28 +979,28 @@ gtk_widget_get_arg (GtkObject   *object,
       GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
       break;
     case ARG_X:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-      if (!aux_info)
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+      if (!aux_info || !aux_info->x_set)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->x;
       break;
     case ARG_Y:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-      if (!aux_info)
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+      if (!aux_info || !aux_info->y_set)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->y;
       break;
     case ARG_WIDTH:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
        GTK_VALUE_INT (*arg) = aux_info->width;
       break;
     case ARG_HEIGHT:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
       if (!aux_info)
        GTK_VALUE_INT (*arg) = -1;
       else
@@ -1970,7 +1989,7 @@ gtk_widget_get_child_requisition (GtkWidget        *widget,
 
   *requisition = widget->requisition;
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   if (aux_info)
     {
       if (aux_info->width > 0)
@@ -2001,7 +2020,7 @@ gtk_widget_size_allocate (GtkWidget       *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
   real_allocation = *allocation;
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   
   if (aux_info)
     {
@@ -3930,11 +3949,26 @@ gtk_widget_get_parent_window   (GtkWidget           *widget)
   return (parent_window != NULL) ? parent_window : widget->parent->window;
 }
 
+/* Update the position from aux_info. Used from gtk_widget_set_uposition
+ * and gtk_widget_set_arg().
+ */
+static void
+gtk_widget_do_uposition (GtkWidget *widget)
+{
+  GtkWidgetAuxInfo *aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+
+  if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
+    gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
+  
+  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
+    gtk_widget_size_allocate (widget, &widget->allocation);
+}
+
 /**
  * gtk_widget_set_uposition:
  * @widget: a #GtkWidget
- * @x: x position
- * @y: y position
+ * @x: x position; -1 to unset x; -2 to leave x unchanged
+ * @y: y position; -1 to unset y; -2 to leave y unchanged
  * 
  *
  * Sets the position of a widget. The funny "u" in the name comes from
@@ -3946,7 +3980,12 @@ gtk_widget_get_parent_window   (GtkWidget           *widget)
  * window; most window managers will do the centering on your behalf
  * if you call gtk_window_set_transient_for(), and it's really not
  * possible to get the centering to work correctly in all cases from
- * application code.
+ * application code. But if you insist, use gtk_window_set_position()
+ * to set #GTK_WIN_POS_CENTER_ON_PARENT, don't do the centering
+ * manually.
+ *
+ * Note that although x and y can be individually unset, the position
+ * is not honoured unless both x and y are set.
  **/
 void
 gtk_widget_set_uposition (GtkWidget *widget,
@@ -3958,25 +3997,33 @@ gtk_widget_set_uposition (GtkWidget *widget,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-  if (!aux_info)
-    {
-      aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
-    }
+  aux_info =_gtk_widget_get_aux_info (widget, TRUE);
 
-  /* keep this in sync with gtk_window_compute_reposition() */
+  /* keep this in sync with gtk_window_set_location() */
   
   if (x > -2)
-    aux_info->x = x;
+    {
+      if (x == -1)
+       aux_info->x_set = FALSE;
+      else
+       {
+         aux_info->x_set = TRUE;
+         aux_info->x = x;
+       }
+    }
+
   if (y > -2)
-    aux_info->y = y;
-  
-  if (GTK_IS_WINDOW (widget) && (aux_info->x != -1) && (aux_info->y != -1))
-    gtk_window_reposition (GTK_WINDOW (widget), x, y);
-  
-  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
-    gtk_widget_size_allocate (widget, &widget->allocation);
+    {
+      if (y == -1)
+       aux_info->y_set = FALSE;
+      else
+       {
+         aux_info->y_set = TRUE;
+         aux_info->y = y;
+       }
+    }
+
+  gtk_widget_do_uposition (widget);
 }
 
 /**
@@ -4014,12 +4061,7 @@ gtk_widget_set_usize (GtkWidget *widget,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-  if (!aux_info)
-    {
-      aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
-    }
+  aux_info =_gtk_widget_get_aux_info (widget, TRUE);
   
   if (width > -2)
     aux_info->width = width;
@@ -4742,7 +4784,7 @@ gtk_widget_finalize (GObject *object)
   if (widget->name)
     g_free (widget->name);
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   if (aux_info)
     gtk_widget_aux_info_destroy (aux_info);
   
@@ -4978,6 +5020,36 @@ gtk_widget_propagate_state (GtkWidget           *widget,
     }
 }
 
+/**
+ * _gtk_widget_get_aux_info:
+ * @widget: a #GtkWidget
+ * @create: if %TRUE, create the structure if it doesn't exist
+ * 
+ * Get the #GtkWidgetAuxInfo structure for the widget.
+ * 
+ * Return value: the #GtkAuxInfo structure for the widget, or
+ *    %NULL if @create is %FALSE and one doesn't already exist.
+ **/
+GtkWidgetAuxInfo *
+_gtk_widget_get_aux_info (GtkWidget *widget,
+                         gboolean   create)
+{
+  GtkWidgetAuxInfo *aux_info;
+  
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  if (!aux_info && create)
+    {
+      aux_info = gtk_widget_aux_info_new ();
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
+
+      aux_info->width = aux_info->height = -1;
+      aux_info->x = aux_info->y = 0;
+      aux_info->x_set = aux_info->y_set = FALSE;
+    }
+  
+  return aux_info;
+}
+
 /*****************************************
  * gtk_widget_aux_info_new:
  *
index 9e37df24f96f86e41ba2ee2685de881891f9f778..88e776692a8c683f8a88e82cce604cb6479a69a4 100644 (file)
@@ -394,6 +394,8 @@ struct _GtkWidgetAuxInfo
   gint y;
   gint width;
   gint height;
+  guint x_set : 1;
+  guint y_set : 1;
 };
 
 struct _GtkWidgetShapeInfo
@@ -679,6 +681,8 @@ void             gtk_widget_class_path         (GtkWidget *widget,
 #  define gtk_widget_unref gtk_object_unref
 #endif /* GTK_TRACE_OBJECTS && __GNUC__ */
 
+GtkWidgetAuxInfo *_gtk_widget_get_aux_info (GtkWidget *widget,
+                                           gboolean   create);
 
 #ifdef __cplusplus
 }
index 8e91f9e2f1db60b6686dea5f0420944dee86089d..f1dacda4b250eccb82f77f20fa4e107f2fb435b3 100644 (file)
@@ -76,7 +76,7 @@ enum {
   PROP_DEFAULT_WIDTH,
   PROP_DEFAULT_HEIGHT,
   PROP_DESTROY_WITH_PARENT,
-
+  
   LAST_ARG
 };
 
@@ -93,7 +93,7 @@ typedef struct {
   GdkGeometry    geometry;     /* Geometry hints */
   GdkWindowHints mask;
   GtkWidget     *widget;       /* subwidget to which hints apply */
-  gint           width;                /* Default size */
+  gint           width;                /* gtk_window_set_default_size () */
   gint           height;
 
   GtkWindowLastGeometryInfo last;
@@ -166,11 +166,11 @@ static void  gtk_window_constrain_size      (GtkWindow       *window,
 static void gtk_window_compute_hints      (GtkWindow         *window, 
                                           GdkGeometry       *new_geometry,
                                           guint             *new_flags);
-static void gtk_window_compute_reposition (GtkWindow         *window,
-                                          gint               new_width,
-                                          gint               new_height,
-                                          gint              *x,
-                                          gint              *y);
+static gboolean gtk_window_compute_reposition (GtkWindow         *window,
+                                              gint               new_width,
+                                              gint               new_height,
+                                              gint              *x,
+                                              gint              *y);
 
 static void gtk_window_read_rcfiles       (GtkWidget         *widget,
                                           GdkEventClient    *event);
@@ -450,6 +450,7 @@ gtk_window_init (GtkWindow *window)
   window->frame_top = 0;
   window->frame_bottom = 0;
   window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+  window->gravity = GDK_GRAVITY_NORTH_WEST;
   window->decorated = TRUE;
   window->mnemonic_modifier = GDK_MOD1_MASK;
   
@@ -1478,8 +1479,24 @@ gtk_window_set_default_size (GtkWindow   *window,
     g_object_notify (G_OBJECT (window), "width");
   if (height >= 0)
     g_object_notify (G_OBJECT (window), "height");
-  
-  gtk_widget_queue_resize (GTK_WIDGET (window));
+
+  if (GTK_WIDGET_REALIZED (window) && window->allow_grow)
+    {
+      /* Resize as if the user had resized */
+      GdkGeometry new_geometry;
+      GdkWindowHints new_flags;
+      
+      gtk_window_compute_hints (window, &new_geometry, &new_flags);
+      gtk_window_constrain_size (window,
+                                 &new_geometry, new_flags,
+                                 width, height,
+                                 &width, &height);          
+      
+      gdk_window_resize (GTK_WIDGET (window)->window,
+                         width, height);
+    }
+  else
+    gtk_widget_queue_resize (GTK_WIDGET (window));
 }
   
 static void
@@ -2457,6 +2474,7 @@ gtk_window_move_resize (GtkWindow *window)
   GtkWindowLastGeometryInfo saved_last_info;
   GdkGeometry new_geometry;
   guint new_flags;
+  gboolean need_reposition;
   gint x, y;
   gint width, height;
   gint new_width, new_height;
@@ -2502,10 +2520,10 @@ gtk_window_move_resize (GtkWindow *window)
   /* From the default size and the allocation, figure out the size
    * the window should be.
    */
-  if (!default_size_changed ||
-      (!window->auto_shrink &&
-       new_width <= widget->allocation.width &&
-       new_height <= widget->allocation.height))
+  if (!window->auto_shrink &&
+      (!default_size_changed ||
+       (new_width <= widget->allocation.width &&
+        new_height <= widget->allocation.height)))
     {
       new_width = widget->allocation.width;
       new_height = widget->allocation.height;
@@ -2519,8 +2537,8 @@ gtk_window_move_resize (GtkWindow *window)
 
   /* compute new window position if a move is required
    */
-  gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
-  if (x != 1 && y != -1 && !(new_flags & GDK_HINT_POS))
+  need_reposition = gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
+  if (need_reposition && !(new_flags & GDK_HINT_POS))
     {
       new_flags |= GDK_HINT_POS;
       hints_changed = TRUE;
@@ -2583,7 +2601,7 @@ gtk_window_move_resize (GtkWindow *window)
           * the new size had been set.
           */
          
-         if (x != -1 && y != -1)
+         if (need_reposition)
            {
              if (window->frame)
                gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
@@ -2632,7 +2650,7 @@ gtk_window_move_resize (GtkWindow *window)
        */
       
       /* request a new window size */
-      if (x != -1 && y != -1)
+      if (need_reposition)
        {
          if (window->frame)
            {
@@ -2675,7 +2693,7 @@ gtk_window_move_resize (GtkWindow *window)
     }
   else
     {
-      if (x != -1 && y != -1)
+      if (need_reposition)
        {
          if (window->frame)
            gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
@@ -2724,6 +2742,10 @@ gtk_window_compare_hints (GdkGeometry *geometry_a,
        geometry_a->height_inc != geometry_b->height_inc))
     return FALSE;
 
+  if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
+      (geometry_a->win_gravity != geometry_b->win_gravity))
+    return FALSE;
+  
   return TRUE;
 }
 
@@ -2837,8 +2859,8 @@ gtk_window_compute_hints (GtkWindow   *window,
   ux = 0;
   uy = 0;
   
-  aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
-  if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
+  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+  if (aux_info && aux_info->x_set && aux_info->y_set)
     {
       ux = aux_info->x;
       uy = aux_info->y;
@@ -2899,13 +2921,16 @@ gtk_window_compute_hints (GtkWindow   *window,
       new_geometry->max_width = requisition.width;
       new_geometry->max_height = requisition.height;
     }
+
+  *new_flags |= GDK_HINT_WIN_GRAVITY;
+  new_geometry->win_gravity = window->gravity;
 }
 
 /* Compute a new position for the window based on a new
- * size. *x and *y will be set to the new coordinates, or to -1 if the
- * window does not need to be moved
+ * size. *x and *y will be set to the new coordinates. Returns
+ * TRUE if the window needs to be moved;
  */
-static void 
+static gboolean
 gtk_window_compute_reposition (GtkWindow  *window,
                               gint        new_width,
                               gint        new_height,
@@ -2915,12 +2940,10 @@ gtk_window_compute_reposition (GtkWindow  *window,
   GtkWidget *widget;
   GtkWindowPosition pos;
   GtkWidget *parent_widget;
+  gboolean result = FALSE;
   
   widget = GTK_WIDGET (window);
 
-  *x = -1;
-  *y = -1;
-
   parent_widget = (GtkWidget*) window->transient_parent;
   
   pos = window->position;
@@ -2940,6 +2963,8 @@ gtk_window_compute_reposition (GtkWindow  *window,
          
          *x = (screen_width - new_width) / 2;
          *y = (screen_height - new_height) / 2;
+
+         result = TRUE;
        }
       break;
 
@@ -2952,6 +2977,8 @@ gtk_window_compute_reposition (GtkWindow  *window,
                                  
           *x = ox + (parent_widget->allocation.width - new_width) / 2;
           *y = oy + (parent_widget->allocation.height - new_height) / 2;
+
+         result = TRUE;
         }
       break;
 
@@ -2966,43 +2993,37 @@ gtk_window_compute_reposition (GtkWindow  *window,
          *y -= new_height / 2;
          *x = CLAMP (*x, 0, screen_width - new_width);
          *y = CLAMP (*y, 0, screen_height - new_height);
+
+         result = TRUE;
        }
       break;
     default:
       if (window->use_uposition)
        {
-         GtkWidgetAuxInfo *aux_info;
-         
-         aux_info = gtk_object_get_data (GTK_OBJECT (window), "gtk-aux-info");
-         if (aux_info &&
-             aux_info->x != -1 && aux_info->y != -1 &&
-             aux_info->x != -2 && aux_info->y != -2)
+         GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+         if (aux_info && aux_info->x_set && aux_info->y_set)
            {
              *x = aux_info->x;
              *y = aux_info->y;
            }
+
+         result = TRUE;
        }
       break;
     }
 
-  if (*x != -1 && *y != -1)
+  if (result)
     {
-      GtkWidgetAuxInfo *aux_info;
+      GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
       
-      /* we handle necessary window positioning by hand here,
-       * so we can coalesce the window movement with possible
-       * resizes to get only one configure event.
-       * keep this in sync with gtk_widget_set_uposition()
-       * and gtk_window_reposition().
-       */
-      gtk_widget_set_uposition (widget, -1, -1); /* ensure we have aux_info */
-      
-      aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
+      aux_info->x_set = aux_info->y_set = TRUE;
       aux_info->x = *x;
       aux_info->y = *y;
 
       window->use_uposition = FALSE;
     }
+
+  return result;
 }
 
 /***********************
@@ -3374,6 +3395,375 @@ gtk_window_unmaximize (GtkWindow *window)
     gdk_window_unmaximize (toplevel);
 }
 
+/**
+ * gtk_window_set_resizeable:
+ * @window: a #GtkWindow
+ * @setting: %TRUE if the user can resize this window
+ *
+ * Sets whether the user can resize a window. Windows are user resizeable
+ * by default.
+ * 
+ **/
+void
+gtk_window_set_resizeable (GtkWindow *window,
+                                gboolean   setting)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (setting)
+    gtk_window_set_policy (window, FALSE, TRUE, FALSE);
+  else
+    gtk_window_set_policy (window, FALSE, FALSE, TRUE);
+}
+
+/**
+ * gtk_window_get_resizeable:
+ * @window: a #GtkWindow
+ * 
+ * Gets the value set by gtk_window_set_resizeable().
+ * 
+ * Return value: %TRUE if the user can resize the window
+ **/
+gboolean
+gtk_window_get_resizeable (GtkWindow *window)
+{
+  g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+  /* allow_grow is most likely to indicate the semantic concept we
+   * mean by "resizeable" (and will be a reliable indicator if
+   * set_policy() hasn't been called)
+   */
+  return window->allow_grow;
+}
+
+
+/**
+ * gtk_window_set_size:
+ * @window: a #GtkWindow
+ * @width: width, or -1 to use the default width
+ * @height: height, or -1 to use the default height
+ *
+ * Sets the size of @window, but only works for resizeable windows
+ * (see gtk_window_set_resizeable()). Setting the size emulates a user
+ * resize operation. Therefore, setting the size less than the minimum
+ * size for the window will simply make the window its minimum size,
+ * and the user will be able to change the size that's set.
+ *
+ * This call also sets the default size of the window, so replaces
+ * gtk_window_set_default_size().
+ *
+ * To set a minimum size, or to set the size of a non-resizeable window,
+ * use gtk_widget_set_usize() on the window. Though normally it makes
+ * more sense to instead call gtk_widget_set_usize() on a child widget inside
+ * the window, rather than the window itself.
+ *
+ * Under the X Window System, window managers are allowed to ignore GTK+'s
+ * request to change a window's size. So your program should not rely on
+ * getting a specific size. (And, as noted in gtk_window_get_size(),
+ * a program that crucially relies on a specific size will generally have
+ * race conditions and be buggy anyway - rather than assuming a
+ * call to gtk_window_set_size() has taken effect, you should react
+ * to configure_event signals on your #GtkWindow.)
+ *
+ * If you set a geometry widget for the window with
+ * gtk_window_set_geometry_hints(), the size applies to the geometry
+ * widget, not the window itself.
+ *
+ * If you've called the deprecated gtk_window_set_policy() function,
+ * gtk_window_set_size() may not behave as expected, due to interaction
+ * with window policies.
+ **/
+void
+gtk_window_set_size (GtkWindow *window,
+                     gint       width,
+                     gint       height)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (width != 0);
+  g_return_if_fail (height != 0);
+  
+  /* set_default_size() uses "0" to mean "unset", but we allow "-1"
+   * for that in this newer function
+   */
+  if (width < 0)
+    width = 0;
+  if (height < 0)
+    height = 0;
+
+  gtk_window_set_default_size (window, width, height);
+}
+
+/**
+ * gtk_window_get_size:
+ * @window: a #GtkWindow
+ * @width: return location for current width, or %NULL
+ * @height: return location for current height, or %NULL
+ * 
+ * Obtains the current size of @window. If the window is not onscreen
+ * (i.e. has not been received its first configure_event after being
+ * shown with gtk_widget_show()), the size will be the size GTK+ will
+ * request for this window when it's shown.  The window manager may
+ * not choose to give the window exactly this requested size.
+ *
+ * In general, code which depends on window size should connect to the
+ * configure_event on the window so that it can respond to changes in
+ * size caused by the user or by the window manager, in addition to
+ * changes in size created by your program.
+ *
+ * If you set a geometry widget for the window with
+ * gtk_window_set_geometry_hints(), the size retrieved is the size of
+ * the geometry widget, not the window itself.
+ * 
+ **/
+void
+gtk_window_get_size (GtkWindow *window,
+                     gint      *width,
+                     gint      *height)
+{
+  GtkWindowGeometryInfo *info;
+  GtkWidget *widget = GTK_WIDGET (window);
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (GTK_WIDGET_REALIZED (window))
+    {
+      gdk_window_get_size (GTK_WIDGET (window)->window,
+                           width, height);
+    }
+  else
+    {
+      GdkGeometry new_geometry;
+      GdkWindowHints new_flags;
+      gint w, h;
+      
+      gtk_widget_size_request (widget, NULL);  
+      gtk_window_compute_default_size (window, &w, &h);
+      
+      gtk_window_compute_hints (window, &new_geometry, &new_flags);
+      gtk_window_constrain_size (window,
+                                 &new_geometry, new_flags,
+                                 w, h,
+                                 &w, &h);
+
+      if (width)
+        *width = w;
+      if (height)
+        *height = h;
+    }
+
+  info = gtk_window_get_geometry_info (window, TRUE);
+  if (info->widget)
+    {
+      gint extra_width = widget->requisition.width - info->widget->requisition.width;
+      gint extra_height = widget->requisition.height - info->widget->requisition.height;
+      
+      if (width)
+        *width -= extra_width;
+      if (height)
+        *height -= extra_height;
+    }
+}
+
+/**
+ * gtk_window_set_location:
+ * @window: a #GtkWindow
+ * @root_x: X position of gravity-determined reference point in root window coordinates
+ * @root_y: Y position of gravity-determined reference point in root window coordinates
+ *
+ * Requests a new position for a #GtkWindow. The position is given in
+ * root window coordinates, and is the position of the window's
+ * "reference point" as determined by the window gravity (see
+ * gtk_window_set_gravity()). By default, the reference point is the
+ * northwest (top left) corner of the window's titlebar.  So if you
+ * set the window position to (0,0), the window's titlebar will end up
+ * in the top left corner of the root window. Note that the root
+ * window does not always correspond to the user's desktop area, so
+ * you may want to call gdk_workspace_get_extents() or
+ * gdk_desktop_get_extents() to decide where to place a window.  The
+ * extents of the root window can be obtained using gdk_screen_width()
+ * and gdk_screen_height().
+ * 
+ **/
+void
+gtk_window_set_location (GtkWindow *window,
+                         gint       root_x,
+                         gint       root_y)
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (window), TRUE);
+
+  aux_info->x_set = aux_info->y_set = TRUE;
+  aux_info->x = root_x;
+  aux_info->y = root_y;
+  
+  gtk_window_reposition (window, root_x, root_y);
+}
+
+/**
+ * gtk_window_get_location:
+ * @window: a #GtkWindow
+ * @root_x: return location for X coordinate of gravity-determined reference point
+ * @root_y: return location for Y coordinate of gravity-determined reference point
+ *
+ * Attempts to obtain the current position of the reference point, as
+ * set by gtk_window_set_position(). This computation is accurate when
+ * the reference point is a corner of the window itself (as with
+ * #GDK_GRAVITY_STATIC), but may not be accurate when the reference
+ * point is a position on the titlebar or window border, because the X
+ * Window System does not provide a reliable way of obtaining this
+ * information. GTK+ will do a "best guess" which may not be fully
+ * accurate with some window managers, but will probably be
+ * reasonable.
+ * 
+ **/
+void
+gtk_window_get_location (GtkWindow *window,
+                         gint      *root_x,
+                         gint      *root_y)
+{
+  GdkRectangle frame_extents;
+  GtkWidget *widget;
+  GtkWidgetAuxInfo *aux_info;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
+  
+  if (GTK_WIDGET_REALIZED (window))
+    {
+      if (window->gravity == GDK_GRAVITY_STATIC)
+        {
+          gdk_window_get_origin (widget->window, root_x, root_y);
+          return;
+        }
+      else
+        {
+          gint x, y;
+          
+          gdk_window_get_frame_extents (widget->window, &frame_extents);
+          
+          x = frame_extents.x;
+          y = frame_extents.y;
+
+          switch (window->gravity)
+            {
+            case GDK_GRAVITY_NORTH:
+            case GDK_GRAVITY_CENTER:
+            case GDK_GRAVITY_SOUTH:
+              x += frame_extents.width / 2;
+              break;
+            case GDK_GRAVITY_SOUTH_EAST:
+            case GDK_GRAVITY_EAST:
+            case GDK_GRAVITY_NORTH_EAST:
+              x += frame_extents.width;
+              break;
+            default:
+              break;
+            }
+
+          switch (window->gravity)
+            {
+            case GDK_GRAVITY_WEST:
+            case GDK_GRAVITY_CENTER:
+            case GDK_GRAVITY_EAST:
+              y += frame_extents.height / 2;
+              break;
+            case GDK_GRAVITY_SOUTH_WEST:
+            case GDK_GRAVITY_SOUTH:
+            case GDK_GRAVITY_SOUTH_EAST:
+              y += frame_extents.height;
+              break;
+            default:
+              break;
+            }
+
+          if (root_x)
+            *root_x = x;
+          if (root_y)
+            *root_y = y;
+        }
+    }
+  else
+    {
+      /* We really don't have a location yet, so we make up some stuff,
+       * using the uposition if it's been set.
+       */
+      if (root_x)
+        *root_x = 0;
+
+      if (root_y)
+        *root_y = 0;
+      
+      aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+      if (aux_info && aux_info->x_set && aux_info->y_set)
+        {
+         *root_x = aux_info->x;
+         *root_y = aux_info->y;
+        }
+    }
+}
+
+/**
+ * gtk_window_set_gravity:
+ * @window: a #GtkWindow
+ * @gravity: window gravity
+ *
+ * Window gravity defines the "reference point" to be used when
+ * positioning or resizing a window. Calls to
+ * gtk_window_set_position() will position a different point on the
+ * window depending on the window gravity. When the window changes size
+ * the reference point determined by the window's gravity will stay in
+ * a fixed location.
+ *
+ * See #GdkGravity for full details. To briefly summarize,
+ * #GDK_GRAVITY_NORTH_WEST means that the reference point is the
+ * northwest (top left) corner of the window
+ * frame. #GDK_GRAVITY_SOUTH_EAST would be the bottom right corner of
+ * the frame, and so on. If you want to position the window contents,
+ * rather than the window manager's frame, #GDK_GRAVITY_STATIC moves
+ * the reference point to the northwest corner of the #GtkWindow
+ * itself.
+ *
+ * The default window gravity is #GDK_GRAVITY_NORTH_WEST.
+ * 
+ **/
+void
+gtk_window_set_gravity (GtkWindow *window,
+                        GdkGravity gravity)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (gravity != window->gravity)
+    {
+      window->gravity = gravity;
+
+      /* This is sort of odd, but it keeps the hints recomputation
+       * in one place. Otherwise we're likely to mess up the
+       * recording of the last hints, etc.
+       */
+      gtk_widget_queue_resize (GTK_WIDGET (window));
+    }
+}
+
+/**
+ * gtk_window_get_gravity:
+ * @window: a #GtkWindow
+ * 
+ * Gets the value set by gtk_window_set_gravity().
+ * 
+ * Return value: window gravity
+ **/
+GdkGravity
+gtk_window_get_gravity (GtkWindow *window)
+{
+  g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
+
+  return window->gravity;
+}
+
 /**
  * gtk_window_begin_resize_drag:
  * @window: a #GtkWindow
@@ -3417,7 +3807,6 @@ gtk_window_begin_resize_drag  (GtkWindow    *window,
                                 timestamp);
 }
 
-
 /**
  * gtk_window_begin_move_drag:
  * @button: mouse button that initiated the drag
index 27526ba457dff8d1d398f6049ea2b93f5879d881..f1460a674461015805bfa200a488035571bbf0d7 100644 (file)
@@ -93,7 +93,9 @@ struct _GtkWindow
 
   guint decorated : 1;
   
-  GdkWindowTypeHint type_hint : 2;
+  GdkWindowTypeHint type_hint : 3;
+
+  GdkGravity gravity : 5;
   
   guint frame_left;
   guint frame_top;
@@ -123,10 +125,6 @@ void       gtk_window_set_wmclass              (GtkWindow           *window,
                                                const gchar         *wmclass_class);
 void       gtk_window_set_role                 (GtkWindow           *window,
                                                 const gchar         *role);
-void       gtk_window_set_policy               (GtkWindow           *window,
-                                               gboolean             allow_shrink,
-                                               gboolean             allow_grow,
-                                               gboolean             auto_shrink);
 void       gtk_window_add_accel_group          (GtkWindow           *window,
                                                GtkAccelGroup       *accel_group);
 void       gtk_window_remove_accel_group       (GtkWindow           *window,
@@ -142,22 +140,41 @@ void       gtk_window_set_type_hint            (GtkWindow           *window,
                                                GdkWindowTypeHint    hint);
 void       gtk_window_set_destroy_with_parent  (GtkWindow           *window,
                                                 gboolean             setting);
-void       gtk_window_set_geometry_hints       (GtkWindow           *window,
-                                               GtkWidget           *geometry_widget,
-                                               GdkGeometry         *geometry,
-                                               GdkWindowHints       geom_mask);
 void       gtk_window_set_decorations_hint     (GtkWindow          *window,
                                                 GdkWMDecoration      decorations);
 void       gtk_window_set_functions_hint       (GtkWindow          *window,
                                                 GdkWMFunction       functions);
 
-/* The following differs from gtk_widget_set_usize, in that
- * gtk_widget_set_usize() overrides the requisition, so sets a minimum
- * size, while this only sets the size requested from the WM.
- */
-void       gtk_window_set_default_size         (GtkWindow           *window,
-                                               gint                 width,
-                                               gint                 height);
+
+void       gtk_window_set_resizeable           (GtkWindow           *window,
+                                                gboolean             setting);
+gboolean   gtk_window_get_resizeable           (GtkWindow           *window);
+
+
+void       gtk_window_set_size                 (GtkWindow           *window,
+                                                gint                 width,
+                                                gint                 height);
+void       gtk_window_get_size                 (GtkWindow           *window,
+                                                gint                *width,
+                                                gint                *height);
+
+void       gtk_window_set_location             (GtkWindow           *window,
+                                                gint                 root_x,
+                                                gint                 root_y);
+void       gtk_window_get_location             (GtkWindow           *window,
+                                                gint                *root_x,
+                                                gint                *root_y);
+
+void       gtk_window_set_gravity              (GtkWindow           *window,
+                                                GdkGravity           gravity);
+GdkGravity gtk_window_get_gravity              (GtkWindow           *window);
+
+
+void       gtk_window_set_geometry_hints       (GtkWindow           *window,
+                                               GtkWidget           *geometry_widget,
+                                               GdkGeometry         *geometry,
+                                               GdkWindowHints       geom_mask);
+
 /* gtk_window_set_has_frame () must be called before realizing the window_*/
 void       gtk_window_set_has_frame            (GtkWindow *window);
 void       gtk_window_set_frame_dimensions     (GtkWindow *window, 
@@ -186,7 +203,6 @@ gboolean gtk_window_activate_mnemonic     (GtkWindow       *window,
 void     gtk_window_set_mnemonic_modifier (GtkWindow       *window,
                                           GdkModifierType  modifier);
 
-
 void     gtk_window_present       (GtkWindow *window);
 void     gtk_window_iconify       (GtkWindow *window);
 void     gtk_window_deiconify     (GtkWindow *window);
@@ -207,6 +223,19 @@ void gtk_window_begin_move_drag   (GtkWindow     *window,
                                    gint           root_y,
                                    guint32        timestamp);
 
+#ifndef GTK_DISABLE_DEPRECATED
+void       gtk_window_set_policy               (GtkWindow           *window,
+                                               gint                 allow_shrink,
+                                               gint                 allow_grow,
+                                               gint                 auto_shrink);
+/* The following differs from gtk_widget_set_usize, in that
+ * gtk_widget_set_usize() overrides the requisition, so sets a minimum
+ * size, while this only sets the size requested from the WM.
+ */
+void       gtk_window_set_default_size         (GtkWindow           *window,
+                                               gint                 width,
+                                               gint                 height);
+#endif
 
 /* --- internal functions --- */
 void       gtk_window_set_focus                (GtkWindow           *window,
index d1ebb32f90db6b8db7844cacff4579e04eab55f6..b8aa151133ac8c726d743c4d031c587be3dbc31e 100644 (file)
@@ -8206,6 +8206,325 @@ create_window_states (void)
     gtk_widget_destroy (window);
 }
 
+/*
+ * Window sizing
+ */
+
+static gint
+configure_event_callback (GtkWidget *widget,
+                          GdkEventConfigure *event,
+                          gpointer data)
+{
+  GtkWidget *label = data;
+  gchar *msg;
+  gint x, y;
+
+  gtk_window_get_location (GTK_WINDOW (widget), &x, &y);
+  
+  msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
+                         "location: %d, %d",
+                         event->x, event->y, event->width, event->height,
+                         x, y);
+  
+  gtk_label_set_text (GTK_LABEL (label), msg);
+
+  g_free (msg);
+
+  return FALSE;
+}
+
+static void
+get_ints (GtkWidget *window,
+          gint      *a,
+          gint      *b)
+{
+  GtkWidget *spin1;
+  GtkWidget *spin2;
+
+  spin1 = g_object_get_data (G_OBJECT (window), "spin1");
+  spin2 = g_object_get_data (G_OBJECT (window), "spin2");
+
+  *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
+  *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
+}
+
+static void
+set_size_callback (GtkWidget *widget,
+                   gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_window_set_size (g_object_get_data (data, "target"),
+                       w, h);
+}
+     
+static void
+set_default_size_callback (GtkWidget *widget,
+                           gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_window_set_default_size (g_object_get_data (data, "target"),
+                               w, h);
+}
+
+static void
+set_usize_callback (GtkWidget *widget,
+                    gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_widget_set_usize (g_object_get_data (data, "target"),
+                        w, h);
+}
+
+static void
+set_location_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  gint x, y;
+  
+  get_ints (data, &x, &y);
+
+  gtk_window_set_location (g_object_get_data (data, "target"),
+                           x, y);
+}
+
+static void
+allow_shrink_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "allow_shrink",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+allow_grow_callback (GtkWidget *widget,
+                     gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "allow_grow",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+auto_shrink_callback (GtkWidget *widget,
+                      gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "auto_shrink",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+gravity_selected (GtkWidget *widget,
+                  gpointer data)
+{
+  gtk_window_set_gravity (G_OBJECT (g_object_get_data (data, "target")),
+                          gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
+}
+
+static GtkWidget*
+window_controls (GtkWidget *window)
+{
+  GtkWidget *control_window;
+  GtkWidget *label;
+  GtkWidget *vbox;
+  GtkWidget *button;
+  GtkWidget *spin;
+  GtkAdjustment *adj;
+  GtkWidget *om;
+  GtkWidget *menu;
+  gint i;
+  
+  control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
+  
+  g_object_set_data (G_OBJECT (control_window),
+                     "target",
+                     window);
+  
+  gtk_signal_connect_object (GTK_OBJECT (control_window),
+                             "destroy",
+                             GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                             GTK_OBJECT (window));
+
+  vbox = gtk_vbox_new (FALSE, 5);
+  
+  gtk_container_add (GTK_CONTAINER (control_window), vbox);
+  
+  label = gtk_label_new ("<no configure events>");
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  
+  gtk_signal_connect (GTK_OBJECT (window),
+                      "configure_event",
+                      GTK_SIGNAL_FUNC (configure_event_callback),
+                      label);
+
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+                                              5.0, 0.0);
+  spin = gtk_spin_button_new (adj, 0, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
+
+  g_object_set_data (G_OBJECT (control_window), "spin1", spin);
+
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+                                              5.0, 0.0);
+  spin = gtk_spin_button_new (adj, 0, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
+
+  g_object_set_data (G_OBJECT (control_window), "spin2", spin);
+
+  button = gtk_button_new_with_label ("Queue resize");
+  gtk_signal_connect_object (GTK_WIDGET (button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
+                             GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_button_new_with_label ("Set size");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_size_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set default size");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_default_size_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set usize");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_usize_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set location");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_location_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_check_button_new_with_label ("Allow shrink");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (allow_shrink_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_check_button_new_with_label ("Allow grow");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (allow_grow_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_check_button_new_with_label ("Auto shrink");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (auto_shrink_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  menu = gtk_menu_new ();
+  
+  i = 0;
+  while (i < 10)
+    {
+      GtkWidget *mi;
+      static gchar *names[10] = {
+        "GDK_GRAVITY_NORTH_WEST",
+        "GDK_GRAVITY_NORTH",
+        "GDK_GRAVITY_NORTH_EAST",
+        "GDK_GRAVITY_WEST",
+        "GDK_GRAVITY_CENTER",
+        "GDK_GRAVITY_EAST",
+        "GDK_GRAVITY_SOUTH_WEST",
+        "GDK_GRAVITY_SOUTH",
+        "GDK_GRAVITY_SOUTH_EAST",
+        "GDK_GRAVITY_STATIC",
+        NULL
+      };
+
+      g_assert (names[i]);
+      
+      mi = gtk_menu_item_new_with_label (names[i]);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+      ++i;
+    }
+  
+  gtk_widget_show_all (menu);
+  
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+
+  gtk_signal_connect (GTK_OBJECT (om),
+                      "changed",
+                      GTK_SIGNAL_FUNC (gravity_selected),
+                      control_window);
+
+  gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
+  
+  gtk_widget_show_all (vbox);
+  
+  return control_window;
+}
+
+void
+create_window_sizing (void)
+{
+  static GtkWidget *window = NULL;
+  
+  if (!window)
+    {
+      GtkWidget *label;
+      
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
+      gtk_container_add (GTK_CONTAINER (window), label);
+      gtk_widget_show (label);
+      
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Window to size");
+
+      gtk_widget_show (window_controls (window));
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
 /*
  * GtkProgressBar
  */
@@ -9848,6 +10167,7 @@ create_main_window (void)
       { "tooltips", create_tooltips },
       { "tree", create_tree_mode_window},
       { "WM hints", create_wmhints },
+      { "window sizing", create_window_sizing },
       { "window states", create_window_states }
     };
   int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
index d1ebb32f90db6b8db7844cacff4579e04eab55f6..b8aa151133ac8c726d743c4d031c587be3dbc31e 100644 (file)
@@ -8206,6 +8206,325 @@ create_window_states (void)
     gtk_widget_destroy (window);
 }
 
+/*
+ * Window sizing
+ */
+
+static gint
+configure_event_callback (GtkWidget *widget,
+                          GdkEventConfigure *event,
+                          gpointer data)
+{
+  GtkWidget *label = data;
+  gchar *msg;
+  gint x, y;
+
+  gtk_window_get_location (GTK_WINDOW (widget), &x, &y);
+  
+  msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
+                         "location: %d, %d",
+                         event->x, event->y, event->width, event->height,
+                         x, y);
+  
+  gtk_label_set_text (GTK_LABEL (label), msg);
+
+  g_free (msg);
+
+  return FALSE;
+}
+
+static void
+get_ints (GtkWidget *window,
+          gint      *a,
+          gint      *b)
+{
+  GtkWidget *spin1;
+  GtkWidget *spin2;
+
+  spin1 = g_object_get_data (G_OBJECT (window), "spin1");
+  spin2 = g_object_get_data (G_OBJECT (window), "spin2");
+
+  *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
+  *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
+}
+
+static void
+set_size_callback (GtkWidget *widget,
+                   gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_window_set_size (g_object_get_data (data, "target"),
+                       w, h);
+}
+     
+static void
+set_default_size_callback (GtkWidget *widget,
+                           gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_window_set_default_size (g_object_get_data (data, "target"),
+                               w, h);
+}
+
+static void
+set_usize_callback (GtkWidget *widget,
+                    gpointer   data)
+{
+  gint w, h;
+  
+  get_ints (data, &w, &h);
+
+  gtk_widget_set_usize (g_object_get_data (data, "target"),
+                        w, h);
+}
+
+static void
+set_location_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  gint x, y;
+  
+  get_ints (data, &x, &y);
+
+  gtk_window_set_location (g_object_get_data (data, "target"),
+                           x, y);
+}
+
+static void
+allow_shrink_callback (GtkWidget *widget,
+                       gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "allow_shrink",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+allow_grow_callback (GtkWidget *widget,
+                     gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "allow_grow",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+auto_shrink_callback (GtkWidget *widget,
+                      gpointer   data)
+{
+  g_object_set (G_OBJECT (g_object_get_data (data, "target")),
+                "auto_shrink",
+                GTK_TOGGLE_BUTTON (widget)->active,
+                NULL);
+}
+
+static void
+gravity_selected (GtkWidget *widget,
+                  gpointer data)
+{
+  gtk_window_set_gravity (G_OBJECT (g_object_get_data (data, "target")),
+                          gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
+}
+
+static GtkWidget*
+window_controls (GtkWidget *window)
+{
+  GtkWidget *control_window;
+  GtkWidget *label;
+  GtkWidget *vbox;
+  GtkWidget *button;
+  GtkWidget *spin;
+  GtkAdjustment *adj;
+  GtkWidget *om;
+  GtkWidget *menu;
+  gint i;
+  
+  control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
+  
+  g_object_set_data (G_OBJECT (control_window),
+                     "target",
+                     window);
+  
+  gtk_signal_connect_object (GTK_OBJECT (control_window),
+                             "destroy",
+                             GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                             GTK_OBJECT (window));
+
+  vbox = gtk_vbox_new (FALSE, 5);
+  
+  gtk_container_add (GTK_CONTAINER (control_window), vbox);
+  
+  label = gtk_label_new ("<no configure events>");
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  
+  gtk_signal_connect (GTK_OBJECT (window),
+                      "configure_event",
+                      GTK_SIGNAL_FUNC (configure_event_callback),
+                      label);
+
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+                                              5.0, 0.0);
+  spin = gtk_spin_button_new (adj, 0, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
+
+  g_object_set_data (G_OBJECT (control_window), "spin1", spin);
+
+  adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -3.0, 800.0, 1.0,
+                                              5.0, 0.0);
+  spin = gtk_spin_button_new (adj, 0, 0);
+
+  gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
+
+  g_object_set_data (G_OBJECT (control_window), "spin2", spin);
+
+  button = gtk_button_new_with_label ("Queue resize");
+  gtk_signal_connect_object (GTK_WIDGET (button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
+                             GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_button_new_with_label ("Set size");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_size_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set default size");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_default_size_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set usize");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_usize_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_button_new_with_label ("Set location");
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "clicked",
+                      GTK_SIGNAL_FUNC (set_location_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_check_button_new_with_label ("Allow shrink");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (allow_shrink_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  button = gtk_check_button_new_with_label ("Allow grow");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (allow_grow_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  
+  button = gtk_check_button_new_with_label ("Auto shrink");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_signal_connect (GTK_WIDGET (button),
+                      "toggled",
+                      GTK_SIGNAL_FUNC (auto_shrink_callback),
+                      GTK_OBJECT (control_window));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  menu = gtk_menu_new ();
+  
+  i = 0;
+  while (i < 10)
+    {
+      GtkWidget *mi;
+      static gchar *names[10] = {
+        "GDK_GRAVITY_NORTH_WEST",
+        "GDK_GRAVITY_NORTH",
+        "GDK_GRAVITY_NORTH_EAST",
+        "GDK_GRAVITY_WEST",
+        "GDK_GRAVITY_CENTER",
+        "GDK_GRAVITY_EAST",
+        "GDK_GRAVITY_SOUTH_WEST",
+        "GDK_GRAVITY_SOUTH",
+        "GDK_GRAVITY_SOUTH_EAST",
+        "GDK_GRAVITY_STATIC",
+        NULL
+      };
+
+      g_assert (names[i]);
+      
+      mi = gtk_menu_item_new_with_label (names[i]);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+      ++i;
+    }
+  
+  gtk_widget_show_all (menu);
+  
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+
+  gtk_signal_connect (GTK_OBJECT (om),
+                      "changed",
+                      GTK_SIGNAL_FUNC (gravity_selected),
+                      control_window);
+
+  gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
+  
+  gtk_widget_show_all (vbox);
+  
+  return control_window;
+}
+
+void
+create_window_sizing (void)
+{
+  static GtkWidget *window = NULL;
+  
+  if (!window)
+    {
+      GtkWidget *label;
+      
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
+      gtk_container_add (GTK_CONTAINER (window), label);
+      gtk_widget_show (label);
+      
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Window to size");
+
+      gtk_widget_show (window_controls (window));
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
 /*
  * GtkProgressBar
  */
@@ -9848,6 +10167,7 @@ create_main_window (void)
       { "tooltips", create_tooltips },
       { "tree", create_tree_mode_window},
       { "WM hints", create_wmhints },
+      { "window sizing", create_window_sizing },
       { "window states", create_window_states }
     };
   int nbuttons = sizeof (buttons) / sizeof (buttons[0]);